package com.eureka.gateway.configurer;

import com.eureka.bclass.base.BaseLoginUserInfo;
import com.eureka.bclass.enums.SysKeyEnum;
import com.eureka.bclass.util.JwtUtil;
import com.eureka.bclass.util.StrUtil;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Objects;

/**
 * @Description: 限流维度配置
 * @Author: lixing
 * @Date: 2021/7/17 14:20
 */
@Component
@Configuration
public class RequestRateLimiterConfig {
    /**
     * @Description 获取请求用户ip作为限流key
     * @Author lixing
     * @Date 2021/7/17 14:21
     * @Param []
     * @return org.springframework.cloud.gateway.filter.ratelimit.KeyResolver
     */
    @Bean
    public HostAddressKeyResolver hostAddressKeyResolver() {
        return new HostAddressKeyResolver();
    }

    /**
     * @Description 获取请求用户id作为限流key
     * @Author lixing
     * @Date 2021/7/17 14:22
     * @Param []
     * @return org.springframework.cloud.gateway.filter.ratelimit.KeyResolver
     */
    @Bean
    public UserKeyResolver userKeyResolver() {
        return new UserKeyResolver();
    }

    /**
     * @Description 获取请求地址的uri作为限流key
     * @Author lixing
     * @Date 2021/7/17 14:26
     * @Param [] 
     * @return org.springframework.cloud.gateway.filter.ratelimit.KeyResolver
     */
    @Bean
    @Primary
    public UrlKeyResolver urlKeyResolver() {
        return new UrlKeyResolver();
    }
}

/**
 * @Description 基于ip进行限流
 * @Author lixing
 * @Date 2021/7/18 14:26
 */
class HostAddressKeyResolver implements KeyResolver {
    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        return Mono.just(Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getHostName());
    }
}

/**
 * @Description 基于用户进行限流
 * @Author lixing
 * @Date 2021/7/18 14:26
 */
class UserKeyResolver implements KeyResolver {
    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        String token = exchange.getRequest().getHeaders().getFirst(SysKeyEnum.TOKEN.getKey());
        if (!StrUtil.isEffective(token)) {
            return Mono.just("default");
        }
        try {
            BaseLoginUserInfo baseLoginUserInfo = JwtUtil.verifyJwtForHs256(token);
            return Mono.just(baseLoginUserInfo.getAccount());
        } catch (Exception e) {
            return Mono.just("default");
        }
    }
}

/**
 * @Description 基于请求地址进行限流
 * @Author lixing
 * @Date 2021/7/18 14:26
 */
class UrlKeyResolver implements KeyResolver {
    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        return Mono.just(exchange.getRequest().getPath().value());
    }
}
